package drds.plus.datasource.connection_restrict;

import java.util.Arrays;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 实现应用连接数限制功能中, 具体某一个槽 (Slot) 的连接数限制。
 */
public final class ConnectionRestrictSlot {
    private final ConnectionRestrictEntry connectionRestrictEntry;
    private final Semaphore semaphore;

    public ConnectionRestrictSlot(ConnectionRestrictEntry connectionRestrictEntry) {
        this.connectionRestrictEntry = connectionRestrictEntry;
        this.semaphore = new Semaphore(connectionRestrictEntry.limits); // Nofair, 带 Spin 性能好一些
    }


    public boolean tryAcquire(final int timeoutInMilliSeconds) throws InterruptedException {
        return semaphore.tryAcquire(timeoutInMilliSeconds, TimeUnit.MILLISECONDS);
    }

    public int availablePermits() {
        return semaphore.availablePermits();
    }

    public int getConnectionNumber() {
        return connectionRestrictEntry.limits - semaphore.availablePermits();
    }

    public int getLimits() {
        return connectionRestrictEntry.limits;
    }

    public void release() {
        semaphore.release();
    }

    public String toString() {
        return "ConnectionRestrictSlot: @" + Integer.toHexString(hashCode()) + " " + Arrays.toString(connectionRestrictEntry.slotKeys) + " " + connectionRestrictEntry.limits;
    }
}
